package com.bjy.qa.agent.mock.forward.http;

import com.bjy.qa.agent.mock.http.BufferedHttpServletRequestWrapper;
import com.bjy.qa.agent.mock.http.MockForward;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.List;

import static java.util.Collections.list;
import static org.apache.commons.io.IOUtils.toByteArray;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.valueOf;

/**
 * 转发用的 HttpRequest 对象
 */
public class ForwardHttpRequest {
  private final Logger logger = LoggerFactory.getLogger(this.getClass());

  /**
   * 得到 RequestEntity 对象
   * @param request HttpServletRequest
   * @param forward MockForward
   * @return
   * @throws IOException
   */
  public RequestEntity<byte[]> getRequestEntity(BufferedHttpServletRequestWrapper request, MockForward forward) throws IOException {
    byte[] body = extractBody(request);
    HttpHeaders headers = extractHeaders(request);
    HttpMethod method = extractMethod(request);
    URI uri = extractUri(request, forward);
    return new RequestEntity<>(body, headers, method, uri);
  }

  /**
   * 得到转发的 URI
   * @param request HttpServletRequest
   * @param forward MockForward
   * @return
   * @throws UnsupportedEncodingException
   */
  private URI extractUri(BufferedHttpServletRequestWrapper request, MockForward forward) throws UnsupportedEncodingException {
    String query = request.getQueryString() == null ? EMPTY : URLDecoder.decode(request.getQueryString(), "utf-8"); // 处理中文被自动编码问题

    URI redirectURL = UriComponentsBuilder.fromUriString(forward.getHost() + forward.getUri()).query(query).build().encode().toUri();
    logger.info("mock 转发到 => {}", redirectURL.toString());
    return redirectURL;
  }

  /**
   * 得到转发的 HttpMethod
   * @param request HttpServletRequest
   * @return
   */
  private HttpMethod extractMethod(BufferedHttpServletRequestWrapper request) {
    return valueOf(request.getMethod());
  }

  /**
   * 得到转发的 HttpHeaders
   * @param request HttpServletRequest
   * @return
   */
  private HttpHeaders extractHeaders(BufferedHttpServletRequestWrapper request) {
    HttpHeaders headers = new HttpHeaders();
    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
      String name = headerNames.nextElement();
      List<String> value = list(request.getHeaders(name));
      headers.put(name, value);
    }
    return headers;
  }

  /**
   * 得到转发的 body
   * @param request HttpServletRequest
   * @return
   * @throws IOException
   */
  private byte[] extractBody(BufferedHttpServletRequestWrapper request) throws IOException {
    return toByteArray(request.getInputStream());
  }
}
